#include "ibma_in.h"

extern sig_atomic_t	g_CLEAN_SPACE_ON_QUIT_flag ;

int InitEnvironment( struct IbmaEnv *p_env )
{
	struct ConfigSpace		config_space ;
	struct ConfigSpace		*p_config_space = NULL ;
	
	SSL_load_error_strings();
	
	strncpy( p_env->netaddr.ip , p_env->ibma_conf.ibms.server.ip , sizeof(p_env->netaddr.ip)-1 );
	p_env->netaddr.port = p_env->ibma_conf.ibms.server.port ;
	
	p_env->http = CreateHttpEnv() ;
	if( p_env->http == NULL )
	{
		ERRORLOGSG( "CreateHttpEnv failed , errno[%d]" , errno );
		return -1;
	}
	
	p_env->http_secure_env = CreateHttpSecureEnv( IBP_HTTPSECURE_SIGN_FLAG_MD5 , IBP_HTTPSECURE_COMPRESS_FLAG_GZIP , 0 ) ;
	if( p_env->http_secure_env == NULL )
	{
		ERRORLOGSG( "CreateHttpSecureEnv failed , errno[%d]" , errno );
		return -1;
	}
	
	p_env->index_space.shm.proj_id = 0 ;
	p_env->index_space.shm.shmkey = ftok( p_env->ibma_conf_pathfilename , p_env->index_space.shm.proj_id ) ;
	if( p_env->index_space.shm.shmkey == -1 )
	{
		ERRORLOGSG( "ftok[%s][%d] failed , errno[%d]" , p_env->ibma_conf_pathfilename , p_env->index_space.shm.proj_id );
		return -1;
	}
	else
	{
		INFOLOGSG( "ftok[%s][%d] ok[0x%X]" , p_env->ibma_conf_pathfilename , p_env->index_space.shm.proj_id , p_env->index_space.shm.shmkey );
	}
	
	p_env->index_space.shm.size = sizeof(struct IndexSpaceAttaching) ;
	p_env->index_space.shm.shmid = shmget( p_env->index_space.shm.shmkey , p_env->index_space.shm.size , IPC_CREAT|0644 ) ;
	if( p_env->index_space.shm.shmid == -1 )
	{
		ERRORLOGSG( "shmget[0x%X] failed , errno[%d]" , p_env->index_space.shm.shmkey , errno );
		return -1;
	}
	else
	{
		INFOLOGSG( "shmget[0x%X] ok , shmid[%d]" , p_env->index_space.shm.shmkey , p_env->index_space.shm.shmid );
	}
	
	p_env->index_space.shm.base = shmat( p_env->index_space.shm.shmid , NULL , 0 ) ;
	if( p_env->index_space.shm.base == NULL )
	{
		ERRORLOGSG( "shmat[%d] failed , errno[%d]" , p_env->index_space.shm.shmid , errno );
		return -1;
	}
	else
	{
		INFOLOGSG( "shmat[%d] ok" , p_env->index_space.shm.shmid );
	}
	
	LocateIndexSpaceAddress( p_env->index_space.shm.base , & (p_env->index_space.index_space_attaching) );
	
	strcpy( p_env->index_space.index_space_attaching->node , p_env->ibma_conf.ibma.node );
	p_env->index_space.index_space_attaching->retry_connect_timeval = p_env->ibma_conf.ibac.retry_connect_timeval ;
	
	p_env->netaddr.sock = -1 ;
	
	p_env->current_proj_id = 0 ;
	INIT_LIST_HEAD( & (p_env->config_space_list.this_node) );
	
	for( p_env->current_proj_id = 1 ; p_env->current_proj_id <= 255 ; p_env->current_proj_id++ )
	{
		memset( & config_space , 0x00 , sizeof(struct ConfigSpace) );
		config_space.shm.shmkey = ftok( p_env->ibma_conf_pathfilename , p_env->current_proj_id ) ;
		if( config_space.shm.shmkey == -1 )
		{
			ERRORLOGSG( "ftok[%s][%d] failed , errno[%d]" , p_env->ibma_conf_pathfilename , p_env->current_proj_id , errno );
			return -1;
		}
		
		config_space.shm.shmid = shmget( config_space.shm.shmkey , 0 , 0644 ) ;
		if( config_space.shm.shmid == -1 )
		{
			continue;
		}
		
		config_space.shm.base = shmat( config_space.shm.shmid , NULL , 0 ) ;
		if( config_space.shm.base == NULL )
		{
			ERRORLOGSG( "shmat[%d] failed , errno[%d]" , config_space.shm.shmid , errno );
			return -1;
		}
		
		p_config_space = (struct ConfigSpace *)malloc( sizeof(struct ConfigSpace) ) ;
		if( p_config_space == NULL )
		{
			ERRORLOGSG( "malloc failed , errno[%d]" , errno );
			return -1;
		}
		memcpy( p_config_space , & config_space , sizeof(struct ConfigSpace) );
		
		list_add_tail( & (p_config_space->this_node) , & (p_env->config_space_list.this_node) );
		INFOLOGSG( "add config_space[0x%X][%d]" , p_config_space->shm.shmkey , p_config_space->shm.shmid );
	}
	
	return 0;
}

void CleanEnvironment( struct IbmaEnv *p_env )
{
	struct ConfigSpace	*p_config_space = NULL ;
	struct ConfigSpace	*p_next_config_space = NULL ;
	
	if( p_env->index_space.shm.shmid > 0 )
	{
		if( p_env->index_space.shm.base )
			shmdt( p_env->index_space.shm.base );
		
		if( g_CLEAN_SPACE_ON_QUIT_flag )
		{
			shmctl( p_env->index_space.shm.shmid , IPC_RMID , NULL );
			
			list_for_each_entry_safe( p_config_space , p_next_config_space , & (p_env->config_space_list.this_node) , struct ConfigSpace , this_node )
			{
				shmctl( p_config_space->shm.shmid , IPC_RMID , NULL );
			}
		}
	}
	
	list_for_each_entry_safe( p_config_space , p_next_config_space , & (p_env->config_space_list.this_node) , struct ConfigSpace , this_node )
	{
		free( p_config_space );
	}
	
	DestroyHttpEnv( p_env->http );
	DestroyHttpSecureEnv( p_env->http_secure_env );
	
	return;
}

